﻿#include "ServiceDemoFuelFiller.h"
#include "../PublicService/SettingData.h"

using namespace BusinessLayer;

DYNAMIC_CREATE(ServiceDemoFuelFiller)

ServiceDemoFuelFiller::ServiceDemoFuelFiller()
{
    run = true;
    workingThread = std::thread(&ServiceDemoFuelFiller::ThreadFunction, this);

    BusinessLayer::ContainerForDevice::instance.getDataPool()
            ->RegisterDataCallback("valve.valveStatus",
                                   [&](QVariant v) -> void
    {
        emit DataChanged("valve.valveStatus", v);
    });
    BusinessLayer::ContainerForDevice::instance.getDataPool()
            ->RegisterDataCallback("pump.rpm",
                                   [&](QVariant v) -> void
    {
        emit DataChanged("pump.rpm", v);
    });
    BusinessLayer::ContainerForDevice::instance.getDataPool()
            ->RegisterDataCallback("pump.working",
                                   [&](QVariant v) -> void
    {
        emit DataChanged("pump.working", v);
    });
}

ServiceDemoFuelFiller::~ServiceDemoFuelFiller()
{
    run = false;
    if (workingThread.joinable())
        workingThread.join();
}

bool ServiceDemoFuelFiller::InitFromSettingData(const QString &path)
{
    valveOpenThresholdRPM = GET_SETTING_INT(path + "/ValveOpenThresholdRPM");
    valveCloseThresholdRPM = GET_SETTING_INT(path + "/ValveCloseThresholdRPM");

    return true;
}

void ServiceDemoFuelFiller::ThreadFunction()
{
    Status statusSave = status;
    while (run)
    {
        if (status == Status::idle && command == Command::start)
        {
            status = Status::starting;
            fillingProcess = 0;
            emit DataChanged("fuelFiller.fillingProcess", fillingProcess);
        }
        else if (status != Status::idle && status != Status::stopping && command == Command::stop)
        {
            status = Status::stopping;
        }

        if (status == Status::starting)
        {
            if (!pump->IsWorking())
                pump->Start();
            if (pump->GetRPM() >= valveOpenThresholdRPM)
            {
                if (valve->IsOn())
                    status = Status::started;
                else
                    valve->On();
            }
        }
        else if (status == Status::started)
        {
            if (fillingProcess < 100)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
                fillingProcess += 1;
                emit DataChanged("fuelFiller.fillingProcess", fillingProcess);
            }
            else
            {
                status = Status::stopping;
                command = Command::stop;
            }
        }
        else if (status == Status::stopping)
        {
            if (pump->IsWorking())
                pump->Stop();
            if (pump->GetRPM() <= valveCloseThresholdRPM)
                valve->Off();
            if (!valve->IsOn())
                status = Status::idle;
        }

        if (statusSave != status)
        {
            emit DataChanged("fuelFiller.status", static_cast<int>(status));
            statusSave = status;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
